<?php

namespace App\Http\Services;

use Illuminate\Support\Facades\Redis;
use App\Http\Model\SystemConfig;
use App\Http\Model\UserBlacklist;
use App\Http\Model\UserVerify;
use App\Http\Model\User;
use App\Http\Model\UnionUser;
use App\Http\Model\FinanceRechargeOrder;
use App\Http\Services\MsgServices;
use App\Http\Model\RoomUser;

/**
 * 用户黑名单
 */
class UserBlacklistServices extends CommonServices
{
    protected $userModel;
    protected $userBlacklistModel;
    protected $systemConfigModel;
    protected $unionUserModel;
    protected $financeRechargeOrderModel;
    protected $msgService;
    protected $roomMsgService;
    protected $roomUserModel;

    public function __construct()
    {
        $this->userModel = new User();
        $this->userBlacklistModel = new UserBlacklist();
        $this->systemConfigModel = new SystemConfig();
        $this->unionUserModel = new UnionUser();
        $this->financeRechargeOrderModel = new FinanceRechargeOrder();
        $this->msgService = new MsgServices();
        $this->roomMsgService = new RoomMsgServices();
        $this->roomUserModel = new RoomUser();
    }

    /**
     * 添加搜索黑名单，当搜索用户到指定次数的时候，添加到黑名单
     * 有的用户频繁搜索用户uid，搜到就发挖人消息
     *
     * @param array $userInfo 用户信息
     * @param int $keyword 搜索的用户id
     * @return void
     */
    public function addUserSearchBlacklist($userInfo, $keyword)
    {
        do {
            $userId = $userInfo['user_id'];
            if(empty($userId)) {
                break;
            }
            //添加进白名单的用户不受规则限制
            $whiteConfig = $this->systemConfigModel->getPrivateMsgWhiteConfig();
            if(in_array($userId, $whiteConfig)) {
                break;
            }
            //用户是否在黑名单中
            $ifBlack = $this->userBlacklistModel->getBlackListByUserId($userId);
            if($ifBlack) {
                break;
            }
            //主播不限制
            $userIfUnion = $this->unionUserModel->getSettleUnionUserIdByUserId($userId);
            if($userIfUnion > 0) {
                break;
            }

            //私聊及搜索限制配置
            $blackConfig = $this->systemConfigModel->getPrivateMsgBlackConfig();

            //累计充值满足指定金额不受限制
            if(!empty($blackConfig['sms_diamond_num'])) {
                $rechargeNum = $this->financeRechargeOrderModel->getRechargeTotal($userId);
                if($rechargeNum >= $blackConfig['sms_diamond_num']) {
                    break;
                }
            }
            //缓存记录
            $this->userBlacklistModel->setUserBlackCounterSearch($userId, $keyword);
            //用户校验是否需要加入黑名单
            $blackConfigUse = [];
            $blackConfigUse['1_minute_search_num'] = empty($blackConfig['1_minute_search_num']) ? 0 : $blackConfig['1_minute_search_num'];
            $blackConfigUse['1_day_search_num'] = empty($blackConfig['1_day_search_num']) ? 0 : $blackConfig['1_day_search_num'];
            $this->userBlacklistModel->userToBlack($userId, $blackConfigUse);
        } while (false);
    }

    /**
     * 解除系统用户黑名单
     */
    public function blackListDelete($userId, $reason='')
    {
        do {
            if(empty($userId)) {
                break;
            }
            
            $this->userBlacklistModel->deleteBlacklist($userId, $reason);
        } while (false);
    }

    /**
     * 新增系统用户黑名单
     */
    public function blackListAdd($userId)
    {
        do {
            if(empty($userId)) {
                break;
            }

            $this->userBlacklistModel->blackListAdd($userId);
        } while (false);
    }

    /**
     * 检查并保存用户私信信息
     */
    public function checkSaveUserMsg($userId, $content, $toUserId, $roomId, $placeType)
    {
        do {
            if(empty($userId) || empty($content)) {
                break;
            }

            //发起用户公会ID
            $userUnionId = $this->unionUserModel->getSettleUnionUserIdByUserId($userId);
            if($userUnionId > 0) {
                break;
            }
            //私聊及搜索限制配置
            $blackConfig = $this->systemConfigModel->getBlackWordConfig();

            //累计充值满足指定金额不受限制
            if(!empty($blackConfig['sms_diamond_num'])) {
                $rechargeNum = $this->financeRechargeOrderModel->getRechargeTotal($userId);
                if($rechargeNum >= $blackConfig['sms_diamond_num']) {
                    break;
                }
            }

            //立即封号
	        $checkRes = $this->_checkMsg($content, 2);
            if(!empty($checkRes['blackWordId'])) {
                $logId = $this->userBlacklistModel->addBlackWordLog(['black_word_id'=>$checkRes['blackWordId'], 'word_desc'=>$checkRes['wordDesc'], 'user_id'=>$userId, 'user_desc'=>$content, 'room_id'=>$roomId, 'place_type'=>$placeType]);

                //封号
                $this->userForbid($userId, ($placeType==1 ? '公屏' : '私信').'包含黑名单语言“'.$checkRes['wordDesc'].'”');

                break;
            }

            //不立即封号
            $checkRes = $this->_checkMsg($content, 1);
            if(!empty($checkRes['blackWordId'])) {
                $logId = $this->userBlacklistModel->addBlackWordLog(['black_word_id'=>$checkRes['blackWordId'], 'word_desc'=>$checkRes['wordDesc'], 'user_id'=>$userId, 'user_desc'=>$content, 'room_id'=>$roomId, 'place_type'=>$placeType]);
                //缓存记录
                $this->userBlacklistModel->setUserBlackCounterWord($userId, $logId);

                $blackConfigUse = [];
                $blackConfigUse['black_hour_num'] = empty($blackConfig['black_hour_num']) ? 0 : $blackConfig['black_hour_num'];
                $blackConfigUse['black_word_num'] = empty($blackConfig['black_word_num']) ? 0 : $blackConfig['black_word_num'];
                //用户校验是否需要加入黑名单
                $this->userBlacklistModel->userToBlack($userId, $blackConfigUse);

                $blackConfigUse = [];
                $blackConfigUse['forbid_hour_num'] = empty($blackConfig['forbid_hour_num']) ? 0 : $blackConfig['forbid_hour_num'];
                $blackConfigUse['forbid_word_num'] = empty($blackConfig['forbid_word_num']) ? 0 : $blackConfig['forbid_word_num'];
                //用户校验是否需要封号
                $this->userToForbid($userId, $blackConfigUse);
            }

        } while (false);
    }

    /**
     * 信息内容检查
     */
    public function _checkMsg($content, $promptlyType)
    {
        $result = ['blackWordId'=>0, 'wordDesc'=>''];
        do {
            if(empty($content) || empty($promptlyType)) {
                break;
            }
            $blackWordList = $this->userBlacklistModel->blackWordAll($promptlyType);
            if(empty($blackWordList)) {
                break;
            }
            //分组
            $blackWordMap = array_chunk($blackWordList, 500);
            foreach($blackWordMap as $val) {
                $pattern = "/" . implode("|",  array_column($val, 'word_desc')) . "/i";    //这里会追加很多个词
                $replacement = '**';
                $contentNew = preg_replace($pattern, $replacement, $content);
                if($content !== $contentNew) {
                    foreach($val as $v2) {
                        if (strpos($content, $v2['word_desc']) !== false) {
                            $result['blackWordId'] = $v2['id'];
                            $result['wordDesc'] = $v2['word_desc'];
                            break;
                        }
                    }
                    break;
                }
            }

        } while (false);
        return $result;
    }

    /**
     * 用户校验是否需要封号
     */
    public function userToForbid($userId, $blackConfig){
        $time = time();

        $log = [];
        do {
            //语言
            if(!empty($blackConfig['forbid_hour_num']) && !empty($blackConfig['forbid_word_num'])) {
                $wordLogIds = [];
                for($i=0;$i<$blackConfig['forbid_hour_num'];$i++) {
                    $cacheKey = $this->userBlacklistModel->userBlackCounterWordKey.$userId.':'.date('YmdH', ($time-3600*$i));
                    $logIds = Redis::SMEMBERS($cacheKey);
                    if(!empty($logIds)) {
                        $wordLogIds = array_unique(array_merge($wordLogIds, $logIds));
                    }
                }
                if(count($wordLogIds) >= $blackConfig['forbid_word_num']) {
                    $log['type'] = 9;
                    $log['desc'] = '私信&公屏内容包含黑名单语言';
                    break;
                }
            }

        } while (false);

        //封号
        if(!empty($log)) {
            $this->userForbid($userId, $log['desc']);
        }
    }

    /**
     * 用户封号
     */
    public function userForbid($userId, $operateInfo)
    {
        do {
            $timeout = 0;
            $userInfo = $this->userModel->get_user($userId);

            $log = [];
            $log['user_id'] = $userId;
            $log['uuid'] = empty($userInfo['user_uid']) ? 0 : $userInfo['user_uid'];
            $log['operate_info'] = $operateInfo;
            $log['operate_type'] = 1;
            $log['block_time'] = 0;
            $log['forbid_type'] = 1;
            $log['operation_id'] = 0;
            $log['reason_img'] = '';
            $log['reason_id'] = 42;

            $this->userModel->set_forbid_user($userId, $timeout);
            $room_id = $this->roomUserModel->get_user_cur_room($userId);
            if (!empty($room_id)){
                // 当前 User 踢出房间
                $this->roomMsgService->command_user_out($room_id, $userId, 0);
                // 通知 房间内其它用户，User离开房间
                $this->roomMsgService->broadcast_user_out($room_id, $userId);
            }

            $this->userModel->userForbid($log);

        } while (false);
    }


}
